244. 在GCE使用filebeat傳到GKE的ECK

WHY

RD說他要搞一台自動錄影的服務,
本來以為只有一個服務,那就掛在GKE上就好了。
但是,他有兩個服務A跟B,兩邊的資料要互通。
真要用GKE硬作也是可以,但如果這個服務本身效能就吃很大,
那用k8s也是要多開一台機器,那不如就用GCE吧。
然後,問題就來了,LOG咧!?
Log出問題時要查,最好也是傳去共同的ECK上面,但ECK在GKE上面。

Solution

抓取log的流程也跟一般的filebeat差不多。
filebeat會從主機上的 /var/lib/docker/containers/*/*.log 抓取。
這邊文字檔的log是docker logs的資料,也就是程式的stdout。

官方簡單說明

Docker-compose.yaml

我是用docker compose ,比較好管理。

 services:
  filebeat:
    image: docker.elastic.co/beats/filebeat:8.15.3
    build: filebeat
    container_name: filebeat
    user: root
    restart: unless-stopped
    environment:
      - ELASTICSEARCH_HOSTS=https://10.60.7.192:9200
      - ELASTICSEARCH_USERNAME=elastic
      - ELASTICSEARCH_PASSWORD=PASSWORD
    labels:
      co.elastic.logs/enabled: "false"
    volumes:
      - ./filebeat.yml:/usr/share/filebeat/filebeat.yml
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./ca.crt:/etc/pki/client/ca.crt
      - ./tls.crt:/etc/pki/client/cert.pem
      - ./tls.key:/etc/pki/client/cert.key
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "2"
    networks:
       - zlm_network
networks:
  zlm_network:
    driver: bridge
    name: zlm_network        

主要會著重於volume的部分。
其他地方可能有點差異會抓幾個講。

General

user: root

不設定的話,在filebeat.yml 的logging 會出現權限不足的錯誤。

  1. network 的設定,讓他跟要抓取log的服務放在一起,故同一個網路名稱。

Volume

  1. filebeat.yml的設定檔連結,這部份沒什麼問題。
    裡面內容會在下面說。
  2. 抓取log的路徑 /var/lib/docker/containers
  3. 掛載SSL憑證
    為什麼要掛載呢?因為ECK在安裝的時候,預設都走ssl,
    但ECK安裝時在GKE上面,而目前filebeat在GCE,
    所以要拿ECK在GKE上面的憑證來用。

重點來了,你怎麼知道要抓哪個憑證來用,
此時我們可以先去看一下GKE的ECK裡面的設定檔。

volumes:
   - name: elastic-internal-http-certificates
     secret:
       secretName: prod-es-http-certs-internal
       defaultMode: 420
       optional: false

此時,就能去decode secret了

kubectl get secret prod-es-http-certs-internal -n elastic-system  -o=jsonpath='{.data.ca\.crt}' | base64 -d;echo

kubectl get secret prod-es-http-certs-internal -n elastic-system  -o=jsonpath='{.data.tls\.crt}' | base64 -d;echo

kubectl get secret prod-es-http-certs-internal -n elastic-system  -o=jsonpath='{.data.tls\.key}' | base64 -d;echo

之後將key ,掛載讓filebeat能夠讀取即可。

ref. Run Filebeat on Docker

Filebeat.yml

filebeat.inputs:
 - type: container
   enabled: true
   paths:
     - '/var/lib/docker/containers/*/*.log'
   tags: ["videosokoban-qa"]

 processors:
   - add_docker_metadata: ~
   - drop_event:
       when:
         not:
           equals:
             container.name: "zlm-server"
 output.elasticsearch:
   hosts:  https://prod-es-http:9200 #https://10.60.7.192:9200
   username: "elastic"
   password: "PASSWORD"
   ssl:
     certificate_authorities:
       - "/etc/pki/client/ca.crt"
     certificate: "/etc/pki/client/cert.pem"
     key: "/etc/pki/client/cert.key"      
   indices:
     - index: "videosokoban-qa-%{+yyyy.MM}"
       when.contains:
         tags: "videosokoban-qa"
 logging:
   metrics.enabled: false
   level: debug
   to_stderr: true
   to_files: true
   files:
     path: /var/log/filebeat
     name: filebeat
     keepfiles: 7
     permissions: 0644      

filebeat.input

要擷取的log來源,
已將本機的路徑掛到docker上面的路徑的。
/var/lib/docker/containers/*/*.log
這個路徑擁有所有的docker logs

type 有分成 container與 docker。

據說是docker只能用在docker上面,
但container可以用在任何的容器服務上面。

type: docker的設定我沒搞出來,有興趣的可以自己試一試。

processors

這邊牽扯到的部分比較多

  1. add_docker_metadata
    增加一些欄位到log裡面,詳細內容可參考 Add Docker metadata
  2. drop_event ,判斷當container_name是 zlm-server的時候,
    就不要紀錄,這個值是先塞資料進去到ECK後,再篩選出來的。
    條件判斷可參考conditions

之前還有用過 drop_fileds ,add_cloud_metadata
其他更多請參考Define processors

output.elasticsearch

  1. host & ssl
    要將log丟去的ECK伺服器位置。

hosts這邊,本來是用GKE的內部負載平衡的ip位置,
但是直接使用ip位置的話,會出現錯誤。

cannot validate certificate for 10.60.7.192 because it doesn't contain any IP SANs

這是因為伺服器的憑證沒有加過IP地址,
看一下 tls.crt,裡面的這段。

244-fig.1.png

這裡並沒有ip位置,所以沒辦法通過驗證。
但這個憑證是ECK自動產生的,
所以換個想法,直接讓服務去呼叫 https://prod-es-http:9200
此時,就是到主機設定一下/etc/hosts
新增

10.60.7.192 prod-es-http

ref. Secure communication with Elasticsearch

  1. indices
    將特定的tag綁定到指定的indices上

ref.Configure the Elasticsearch output

logging

除錯時,
可以先將to_stderr: true 開啟。
可直接用docker logs filebeat 看 log。

注意,如果要用 to_files, docker-compose.yaml 記得加上 user: root
否則會發生權限不足的情況。

ref. Configure logging

官方的filebeat.yaml ,請參考 filebeat.reference.yml